<?php

class Files extends \Model {
    
    static public $table = 'files';
    
    protected $_fillable = [
        'md5' => 'str',
        'type' => 'str',
        'file' => 'str',
        'size' => 'int',
    ];
    
    private $imgMaxWidth = 750;
    private $imgMaxHeight = 1200;
    
    public function setImgMaxSize($width, $height) {
        $this->imgMaxWidth = $width;
        $this->imgMaxHeight = $height;
    }
    
    public function getByMd5($md5) {
        $where = [
            'md5' => $md5
        ];
        $result = Db()->getRow(static::$table)->where($where)->result();
        if ($result) {
            if ($result['file'] && is_file(PUBLIC_PATH . $result['file'])) {
                return $result;
            } else {
                Db()->delete(static::$table, ['id' => $result['id']]);
                return false;
            }
        }
        return false;
    }
    
    public function removeByFile($file) {
        $where = [
            'file' => $file
        ];
        
        $result = Db()->delete(static::$table, $where);
        
        if ($result) {
            if (is_file(PUBLIC_PATH . $file)) {
                unlink(PUBLIC_PATH . $file);
            }
        }
        
        return $result;
    }
    
    const TYPE_IMAGE = 'image';
    const TYPE_FILE = 'file';
    
    public function addBase64Image(&$base64_from_post, $upload_relative_dir = '') {
        
        $base64_image = str_replace(' ', '+', $base64_from_post); // post的数据里面，加号会被替换为空格，需要替换回来
        
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image, $matches)) {
            
            if ($matches[2] == 'jpeg') {
                $file_ext = '.jpg';
            } else {
                $file_ext = '.' . $matches[2];
            }
            
            if (!in_array($file_ext, array('.jpg', '.png', '.gif'))) {
                return error('图片格式不符合要求，请上传JPG或PNG格式的图片');
            }
            
            $file_data = base64_decode(str_replace($matches[1], '', $base64_image));
            
            $tmpDir = DATA_PATH . '/Temp/chunk';
            
            if (!file_exists($tmpDir)) {
                @mkdir($tmpDir, 0775, true);
            }
            
            $temp_file_path = $tmpDir . '/' . uniqid("file_");
            
            $file_size = file_put_contents($temp_file_path, $file_data);
            
            if (!$file_size) {
                return error('写入文件到磁盘失败3');
            }
            
            $file_url = Files()->addFrom($temp_file_path, $upload_relative_dir, $file_ext);
            
            if (is_error($file_url)) {
                @unlink($temp_file_path);
                return error(error_message($file_url));
            }
            
            return $file_url;
            
        } else {
            return error('不是BASE64格式的图片');
        }
        
    }
    
    public function addFrom($src_file_path, $upload_relative_dir = '', $file_ext = '') {
        
        $file_ext = $file_ext ? $file_ext : fileExt($src_file_path);
        $dir = UPLOAD_PATH . trim($upload_relative_dir, '/');
        $dst_file_path = file_date_path($dir, $file_ext);
        
        $is_zip = stripos($src_file_path, 'zip://') === 0;
        
        if ($is_zip) {
            $file_data = file_get_contents($src_file_path);
            $md5 = md5($file_data);
        } else {
            $md5 = md5_file($src_file_path);
        }
        
        // 判断文件是否存在
        $md5_file = Files()->getByMd5($md5);
        
        if (!$md5_file) { // 不存在，添加记录
            
            if ($is_zip) {
                $result = file_put_contents($dst_file_path, $file_data);
                if (!$result) {
                    return error('写入文件到磁盘失败1');
                }
            } else {
                $result = @rename($src_file_path, $dst_file_path); // 移动文件
                if (!$result) {
                    return error('写入文件到磁盘失败2');
                }
            }
            
            $file_size = filesize($dst_file_path);
            
            if (\Image::thumbImg($dst_file_path, $dst_file_path, $this->imgMaxWidth, $this->imgMaxHeight)) {
                $file_type = self::TYPE_IMAGE;
            } else {
                $file_type = self::TYPE_FILE;
            }
            
            $file_url = str_replace(UPLOAD_PATH, UPLOAD_URL, $dst_file_path);
            
            $data = [
                'md5' => $md5,
                'type' => $file_type,
                'file' => $file_url,
                'size' => $file_size,
            ];
            
            $result = parent::add($data);
            
            if (!$result) {
                return error('写入文件记录失败');
            }
            
        } else {
            
            $file_url = $md5_file['file'];
            
        }
        
        if (is_error($file_url)) {
            return error(error_message($file_url));
        }
        
        if (!$is_zip && is_file($src_file_path)) {
            @unlink($src_file_path);
        }
        
        return $file_url;
    }
    
}
